package com.foogui.primary.consume;

import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 利用Condition实现生产者-消费者模型
 */
public class ConsumeByConditionDemo {
    private static ReentrantLock lock = new ReentrantLock();
    private static Condition consumerQueue = lock.newCondition();
    private static Condition produceQueue = lock.newCondition();

    private static LinkedList<Integer> queue = new LinkedList<>();

    private static int maxSize = 5;
    private static AtomicInteger count = new AtomicInteger();

    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            es.execute(new Producer());
        }
        for (int i = 0; i < 10; i++) {
            es.execute(new Consumer());
        }


    }

    static class Consumer implements Runnable {


        @Override
        public void run() {

            try {
                lock.lock();
                while (queue.isEmpty()) {
                    try {
                        consumerQueue.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("消费者" + Thread.currentThread().getName() + "，消费了数据：" + queue.removeFirst());
                count.decrementAndGet();
                produceQueue.signalAll();
            } finally {
                lock.unlock();
            }
        }
    }

    static class Producer implements Runnable{

        @Override
        public void run() {
            try {
                lock.lock();
                while (count.get()==maxSize) {
                    try {
                        produceQueue.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                // 随机生成数据
                int i = new Random().nextInt();
                queue.addLast(i);
                count.addAndGet(1);
                System.out.println("生产者" + Thread.currentThread().getName() + "，生产了了数据：" + i);
                consumerQueue.signalAll();
            } finally {
                lock.unlock();
            }
        }
    }
}
